﻿using System;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using ImageLib;

namespace ImageDownloader
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ImageItemCollection collection;
        private ParserCollection parsers = new ParserCollection();
        private Parser parser;

        public MainWindow()
        {
            try
            {
                InitializeComponent();
                urlField.Focus();
            }
            catch (Exception ex) { }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            string path = System.Windows.Forms.Application.StartupPath;
            string[] pluginFiles = Directory.GetFiles(path, "*.dll");

            Console.WriteLine(pluginFiles.Length + " Dlls found in path : " + path);
            foreach (String s in pluginFiles)
            {
                RegisterPlugin(s);
            }
            if (parsers.Count > 0)
            {
                parser = parsers[0];
                if (parsers.Count > 1)
                {
                    Console.WriteLine(parsers.Count + " Dll have been registered.");
                }
                else
                {
                    Console.WriteLine("1 Dll has been registered.");
                }
            }
        }

        public Boolean RegisterPlugin(String s)
        {
            Console.WriteLine("Loading : " + s);
            try
            {
                Assembly _a = Assembly.LoadFile(s);
                if (_a != null)
                {
                    Type[] types = _a.GetTypes();
                    foreach (Type t in types)
                    {
                        try
                        {
                            if (typeof(IParser).IsAssignableFrom(t))
                            {
                                parsers.Add(Activator.CreateInstance(t) as Parser);
                                parsers[parsers.Count - 1].TaskCompleted += new ParseCompletedEventHandler(OnParsingOver);
                                Console.WriteLine("Dll : " + parsers[parsers.Count - 1].getName() + " / Version : " + parsers[parsers.Count - 1].getVersion() + " has been registered.");
                            }
                        }
                        catch (Exception ex) { Console.WriteLine(ex.Message); }
                    }
                }
            }
            catch (Exception ex) 
            {
                Console.WriteLine(ex.Message);
                return false;
            }
            return true;
        }

        public Boolean TestPlugin(String s)
        {
            Console.WriteLine("Testing : " + s);
            try
            {
                Assembly _a = Assembly.LoadFile(s);
                if (_a != null)
                {
                    Type[] types = _a.GetTypes();
                    foreach (Type t in types)
                    {
                        try
                        {
                            if (typeof(IParser).IsAssignableFrom(t))
                            {
                                return true;
                            }
                        }
                        catch (Exception ex) { Console.WriteLine(ex.Message); }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return false;
        }

        public String SavePlugin(String s) {
            try
            {
                String filename = Path.GetFileName(s);
                String path = System.Windows.Forms.Application.StartupPath;
                path += Path.AltDirectorySeparatorChar + filename;
                File.Copy(s, path, true);
                return path;
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }
            return String.Empty;
        }

        #region UI Modifiers

        private void deleteSelection()
        {
            System.Windows.Forms.DialogResult result = System.Windows.Forms.MessageBox.Show(MSG.msg4002, "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk);
            if (result == System.Windows.Forms.DialogResult.Yes && collection != null)
            {
                for (int i = collection.Count - 1; i >= 0; i--)
                {
                    ImageItem item = collection[i];
                    Console.WriteLine("Checking item : " + item.Name);
                    if (item.Selected == true)
                    {
                        Console.WriteLine("Removing item : " + item.Name);
                        collection.Remove(item);
                    }
                }
            }
        }

        private void enableUI()
        {
            urlField.IsEnabled = true;
            pathField.IsEnabled = true;
            browseButton.IsEnabled = true;
            checkButton.IsEnabled = true;
            downloadButton.IsEnabled = true;
        }

        private void disableUI()
        {
            urlField.IsEnabled = false;
            pathField.IsEnabled = false;
            browseButton.IsEnabled = false;
            checkButton.IsEnabled = false;
            downloadButton.IsEnabled = false;
        }

        private void setCursor(System.Windows.Input.Cursor cursor)
        {
            this.Cursor = cursor;
        }

        #endregion

        #region UI Click Events

        private void quit_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void browseButton_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.ShowDialog();
            if (dialog.SelectedPath != String.Empty)
            {
                pathField.Text = dialog.SelectedPath;
            }
        }

        private void downloadButton_Click(object sender, RoutedEventArgs e)
        {
            if (collection == null)
            {
                System.Windows.Forms.MessageBox.Show(MSG.errno4007, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (urlField.Text != String.Empty && pathField.Text != String.Empty)
            {
                foreach (ImageItem i in collection)
                {
                    if (i.Checked == true)
                        i.Save(pathField.Text);
                }
            }
            else
            {
                System.Windows.Forms.MessageBox.Show(MSG.errno4006, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void linksButton_Click(object sender, RoutedEventArgs e)
        {

        }

        private void checkButton_Click(object sender, RoutedEventArgs e)
        {
            if (parser == null)
            {
                System.Windows.Forms.MessageBox.Show(MSG.errno4005, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (urlField.Text != String.Empty)
            {
                Dispatcher.Invoke(
                    DispatcherPriority.Normal,
                    new Action(disableUI));

                Dispatcher.Invoke(
                    DispatcherPriority.Normal,
                    new Action<System.Windows.Input.Cursor>(setCursor),
                    System.Windows.Input.Cursors.Wait);
                
                parser.ParseAsync(urlField.Text);
            }
            else
            {
                System.Windows.Forms.MessageBox.Show(MSG.errno4004, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void help_Click(object sender, RoutedEventArgs e)
        {

        }

        private void deselect_Click(object sender, RoutedEventArgs e)
        {
            listView.SelectedIndex = -1;
        }

        private void selectall_Click(object sender, RoutedEventArgs e)
        {
            listView.SelectAll();
        }

        private void remove_Click(object sender, RoutedEventArgs e)
        {
            deleteSelection();
        }

        private void checkall_Click(object sender, RoutedEventArgs e)
        {
            if (collection != null)
            foreach (ImageItem item in collection)
            {
                item.Checked = true;
            }
        }

        private void uncheckall_Click(object sender, RoutedEventArgs e)
        {
            if (collection != null)
            foreach (ImageItem item in collection)
            {
                item.Checked = false;
            }
        }

        private void PluginButton_Checked(object sender, RoutedEventArgs e)
        {
            Console.WriteLine(parser);
            PluginWindow pg = new PluginWindow(this);
            pg.SetParsers(parsers);
            pg.SetCurrentParser(parser);
            pg.ShowDialog();
            Console.WriteLine(parser);
        }

        #endregion

        #region UI Mouse Events

        private void listView_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            aroundBorder.BorderBrush = new SolidColorBrush(Color.FromArgb(0xFF,0xB7,0xD9,0xED));
            upperBorder.BorderBrush = new SolidColorBrush(Color.FromArgb(0xFF,0x42,0x7F,0xB0));
        }

        private void listView_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            aroundBorder.BorderBrush = new SolidColorBrush(Color.FromArgb(0xFF,0xE3,0xE9,0xEF));
            upperBorder.BorderBrush = new SolidColorBrush(Color.FromArgb(0xFF,0xAB,0xAD,0xB3));
        }

        private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            foreach (ImageItem item in e.AddedItems)
            {
                item.Selected = true;
            }
            foreach (ImageItem item in e.RemovedItems)
            {
                item.Selected = false;
            }
        }

        private void RibbonGallery_SelectionChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {

            Console.WriteLine(parser + " is Selected.");
        }

        #endregion

        #region UI Key Events

        private void listView_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                deleteSelection();
            }
        }

        #endregion

        #region Other Event Handlers

        private void OnParsingOver(object sender, ParseCompletedEventArgs args)
        {
            collection = null;
            collection = args.Collection.Clone() as ImageItemCollection;
            if (collection.Count == 0)
            {
                System.Windows.Forms.MessageBox.Show(MSG.msg4001, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                listView.ItemsSource = collection;
            }

            Dispatcher.Invoke(
                DispatcherPriority.Normal,
                new Action<System.Windows.Input.Cursor>(setCursor),
                System.Windows.Input.Cursors.Arrow);

            Dispatcher.Invoke(
                DispatcherPriority.Normal,
                new Action(enableUI));
        }

        #endregion

    }
}